import java.util.ArrayList;

public class Centroid implements Cloneable {

	private ArrayList<Double> values;
	private String classe;
	private int instances;
	private boolean ready;
	private boolean overall;

	public Centroid(String classe, int nattrs) {
		this.classe = classe;
		this.ready = false;
		this.overall = false;
		this.instances = 0;

		this.values = new ArrayList<Double>(nattrs);
		for (int i = 0; i < nattrs; i++) {
			this.values.add(0.0);
		}
	}

	public Centroid() {

	}

	@Override
	public Object clone() {
		Centroid centroid = new Centroid();

		centroid.classe = new String(classe);
		centroid.instances = instances;
		centroid.ready = ready;
		centroid.overall = overall;
		centroid.values = new ArrayList<Double>(values.size());

		for (int i = 0; i < values.size(); i++) {
			centroid.values.add(new Double(values.get(i)));
		}

		return centroid;
	}

	@Override
	public String toString() {
		StringBuffer buffer = new StringBuffer();

		for (Double value : values) {
			buffer.append(String.format("%f\t", value));
		}

		return buffer.toString();
	}

	public void addSample(Sample sample) throws Exception {
		if (!classe.equals(sample.getClasse()) && !this.isOverall()) {
			throw new Exception("Sample de classe diferente do centroide");
		}

		if (isReady()) {
			throw new Exception("Centroide ja calculado");
		}

		ArrayList<Double> sampleValues = sample.getValues();

		for (int i = 0; i < sampleValues.size(); i++) {
			Double newValue = this.values.get(i) + sampleValues.get(i);
			this.values.set(i, newValue);
		}

		this.instances++;
	}

	public void calculate() throws Exception {
		if (isReady()) {
			throw new Exception("Centroide ja calculado");
		}

		for (int i = 0; i < this.values.size(); i++) {
			Double newValue = this.values.get(i) / this.instances;
			this.values.set(i, newValue);
			this.ready = true;
		}
	}

	public String getClasse() {
		return classe;
	}

	public void setClasse(String classe) {
		this.classe = classe;
	}

	public ArrayList<Double> getValues() {
		return values;
	}

	public void setValues(ArrayList<Double> values) {
		this.values = values;
	}

	public int getInstances() {
		return instances;
	}

	public void setInstances(int instances) {
		this.instances = instances;
	}

	public boolean isReady() {
		return ready;
	}

	public void setReady(boolean ready) {
		this.ready = ready;
	}

	public boolean isOverall() {
		return overall;
	}

	public void setOverall(boolean overall) {
		this.overall = overall;
	}

}
